#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
工具模块 - 通用工具函数
"""

import os
import platform
import numpy as np
import cv2
from config import SUPPORTED_IMAGE_FORMATS, WINDOW_SCALE_FACTOR, MIN_WINDOW_WIDTH, MAX_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MAX_WINDOW_HEIGHT


def check_wsl_environment():
    """检查是否在WSL环境中"""
    try:
        with open('/proc/version', 'r') as f:
            return 'microsoft' in f.read().lower()
    except:
        return False


def setup_display_environment():
    """设置WSL2的显示环境"""
    is_wsl = check_wsl_environment()
    
    if is_wsl:
        # 设置DISPLAY环境变量（如果使用X11转发）
        if 'DISPLAY' not in os.environ:
            os.environ['DISPLAY'] = ':0.0'
        
        # 检查是否可以显示窗口
        try:
            # 尝试创建一个测试窗口
            test_img = np.zeros((100, 100, 3), dtype=np.uint8)
            cv2.imshow('WSL2_Test', test_img)
            cv2.waitKey(1)
            cv2.destroyWindow('WSL2_Test')
            print("✓ GUI显示环境正常")
            return True
        except Exception as e:
            print(f"⚠ GUI显示可能有问题: {e}")
            print("建议:")
            print("1. 安装VcXsrv或X410")
            print("2. 设置DISPLAY环境变量")
            print("3. 或使用无头模式（保存图片而不显示）")
            return False
    
    return True


def rgb565_to_rgb888(data, width, height):
    """
    RGB565格式转换为RGB888 - 使用大端序解析(与STM32匹配)
    
    Args:
        data: RGB565二进制数据
        width: 图像宽度
        height: 图像高度
        
    Returns:
        RGB888的numpy数组，失败时返回None
    """
    try:
        image_size = width * height * 2
        if len(data) != image_size:
            print(f"警告: 数据长度不匹配，期望{image_size}字节，实际{len(data)}字节")
            return None
        
        pixel_count = width * height
        
        # 创建RGB图像数组
        rgb888 = np.zeros((height, width, 3), dtype=np.uint8)
        
        # 逐像素转换 (使用大端序解析)
        for i in range(pixel_count):
            byte1 = data[i * 2]     # 高字节
            byte2 = data[i * 2 + 1] # 低字节
            rgb565 = (byte1 << 8) | byte2   # 大端序组合
            
            # 提取RGB分量
            r = ((rgb565 >> 11) & 0x1F) * 255 // 31  # 5位红色扩展到8位
            g = ((rgb565 >> 5) & 0x3F) * 255 // 63   # 6位绿色扩展到8位
            b = (rgb565 & 0x1F) * 255 // 31          # 5位蓝色扩展到8位
            
            # 计算像素位置 (行列坐标)
            row = i // width
            col = i % width
            
            # 存储为RGB格式
            rgb888[row, col] = [r, g, b]
        
        return rgb888
        
    except Exception as e:
        print(f"图像格式转换错误: {e}")
        return None


def get_images_from_directory(directory):
    """获取目录中的图像文件列表"""
    if not os.path.exists(directory):
        return []
    
    image_files = [f for f in os.listdir(directory) 
                   if f.lower().endswith(SUPPORTED_IMAGE_FORMATS)]
    
    # 按文件名排序以确保顺序一致
    image_files.sort()
    return image_files


def ensure_directory_exists(directory):
    """确保目录存在，如果不存在则创建"""
    if not os.path.exists(directory):
        os.makedirs(directory)
        return False  # 目录是新创建的
    return True  # 目录已存在


def check_face_recognition_library():
    """检查face_recognition库是否已安装"""
    try:
        import face_recognition
        print("✓ face_recognition库已安装")
        return True
    except ImportError:
        print("✗ 未安装face_recognition库")
        print("请运行启动脚本进行安装")
        return False


def print_system_info():
    """打印系统信息"""
    print("OV7670人脸识别系统 - WSL2 Ubuntu版本")
    print("===================================")
    
    # 检查WSL环境
    try:
        with open('/proc/version', 'r') as f:
            if 'microsoft' in f.read().lower():
                print("✓ 检测到WSL2环境")
            else:
                print("⚠ 未检测到WSL2环境，可能在原生Linux中运行")
    except:
        pass
    
    print("功能说明:")
    print("- 从OV7670相机通过串口接收图像")
    print("- 实时进行人脸检测和识别")
    print("- 支持多人脸同时识别")
    print("- 适配WSL2环境")
    print("- 支持Debug模式测试")
    print()


def get_mode_choice():
    """获取用户选择的运行模式"""
    print("运行模式:")
    print("1. 正常模式 - 从串口接收OV7670相机数据")
    print("2. Debug模式 - 从test文件夹读取图片进行测试")
    
    try:
        mode_choice = input("请选择模式 (1/2，默认1): ").strip()
        return mode_choice == '2'
    except (ValueError, KeyboardInterrupt):
        print("使用默认正常模式")
        return False


def print_control_help(debug_mode):
    """打印控制键说明"""
    if debug_mode:
        print("\nDebug模式控制说明:")
        print("  'q' - 退出程序")
        print("  's' - 保存当前帧")
        print("  'r' - 重新加载已知人脸")
        print("  'n' - 手动切换到下一张图像")
        print("  'space' - 切换自动/手动模式")
        print("  'a' - 切换报警功能开关")
    else:
        print("控制键:")
        print("  'q' - 退出程序")
        print("  's' - 保存当前帧")
        print("  'r' - 重新加载已知人脸")
        print("  'a' - 切换报警功能开关")
    print()


def format_filename(prefix, frame_count, extension='.jpg'):
    """格式化文件名"""
    import time
    timestamp = int(time.time())
    return f'{prefix}_frame_{frame_count}_{timestamp}{extension}'


def calculate_smart_window_size(image_width, image_height):
    """
    根据图像尺寸智能计算合适的窗口大小
    
    Args:
        image_width: 图像宽度
        image_height: 图像高度
        
    Returns:
        tuple: (窗口宽度, 窗口高度)
    """
    # 基础计算：图像尺寸乘以缩放因子
    base_width = int(image_width * WINDOW_SCALE_FACTOR)
    base_height = int(image_height * WINDOW_SCALE_FACTOR)
    
    # 应用最小和最大限制
    window_width = max(MIN_WINDOW_WIDTH, min(MAX_WINDOW_WIDTH, base_width))
    window_height = max(MIN_WINDOW_HEIGHT, min(MAX_WINDOW_HEIGHT, base_height))
    
    # 保持宽高比，如果需要调整的话
    image_aspect_ratio = image_width / image_height
    window_aspect_ratio = window_width / window_height
    
    # 如果窗口宽高比和图像宽高比差别太大，调整窗口尺寸
    if abs(window_aspect_ratio - image_aspect_ratio) > 0.1:
        if window_aspect_ratio > image_aspect_ratio:
            # 窗口太宽，调整宽度
            window_width = int(window_height * image_aspect_ratio)
        else:
            # 窗口太高，调整高度
            window_height = int(window_width / image_aspect_ratio)
    
    # 确保调整后仍在范围内
    window_width = max(MIN_WINDOW_WIDTH, min(MAX_WINDOW_WIDTH, window_width))
    window_height = max(MIN_WINDOW_HEIGHT, min(MAX_WINDOW_HEIGHT, window_height))
    
    return window_width, window_height 